<?php
/**
 * Created by PhpStorm.
 * User: 96151
 * Date: 2019/1/11
 * Time: 10:56
 */

/**
 * Class ArticlePushTplFormat
 * 组合生成文章数据
 */
namespace app\common\service;

use app\common\library\CommonFun;
use app\common\model\article\PublishArticleModel;
use app\common\model\coin\CoinReportModel;
use app\common\model\coin\CoinRuntimeModel;
use app\common\redis\ApiNonceRedis;
use app\common\redis\ArticleCTRRedis;
use app\common\redis\ArticlePublicRedis;
use app\common\redis\PythonPushRedis;
use Twig_Environment;
use Twig_Loader_Filesystem;

class ArticlePushTplFormat
{
    /**
     * @var Twig_Environment
     */
    public $view;

    public function __construct()
    {
        $loader = new Twig_Loader_Filesystem(CommonPath."service/ArticlePushTpl/templates");
        //实例化视图类
        $this->view    = new Twig_Environment( $loader, ["cache"=> CommonPath."service/ArticlePushTpl/cache"] );
    }

    /**
     * 获取24小时市场报告html文件
     * @param $coin_id_list
     * @return array
     */
    public function market_report( $coin_id_list )
    {
        // 获取币种信息
        $modelCoinRuntime = CoinRuntimeModel::getInstance();
        $coinDataList = $modelCoinRuntime->muti_get_data_by_id_list($coin_id_list, false);

        // 币种行情信息
        $pythonApi = new PythonApiService();
        $exchange = "global";
        $quote = CoinRuntimeModel::USD_ID;
        $base_quote_list = [];

        foreach ( $coin_id_list as $_coin_id ) {
            $base_quote_list[$_coin_id] = [$quote];
        }

        $tickerList = $pythonApi->mutiGetTickerList($exchange, $base_quote_list);

        // 计算涨跌幅排行
        if ( $tickerList && is_array( $tickerList ) ) {
            // 24H 涨跌幅排序 降序
            CommonFun::array_sort($tickerList, 'change_pct_24h', 'DESC', true, SORT_NUMERIC );
        } else {
            return false;
        }

        foreach ( $tickerList as $key => &$value ){
            $value['token_id'] = explode("-", $key )[0];
            $value['symbol'] = $coinDataList[$value['token_id']]['symbol'];
        }

        // 获取最大值
        $rise_max = array_shift( $tickerList );


        if ( $tickerList ){
            $fall_max = array_pop( $tickerList );
        } else {
            $fall_max = $rise_max;
        }

        if ( (float) $rise_max['change_pct_24h'] < 0 ){
            $rise_max = array();
        }

        if ( $fall_max && ( (float) $fall_max['change_pct_24h'] ) > 0 ){
            $fall_max = array();
        }

        $market_report_global =  $this->market_report_global();

        $market_report_global['market_list'] = CommonFun::json_encode2( $market_report_global['market_list'] );
        $market_report_global['volume_list'] = CommonFun::json_encode2( $market_report_global['volume_list'] );

        $market_report_global['rise_max'] = $rise_max;
        $market_report_global['fall_max'] = $fall_max;

//        $this->view->assign(  $market_report_global );
        $template = $this->view->load("test_fetch.html");
        $content =  $template->render( $market_report_global );

        $title = "你的24小时币市行情报告";
        $summary = "一文掌握今日市场大小事。立即查看>>";

        $coin_id_list = array_map( function( $value ){
            return (int)$value;
        }, $coin_id_list );

        sort( $coin_id_list );

        $PublishArticleModel = PublishArticleModel::getInstance();

        // 插入文章
        $insert = [
            'spider_id' => 0,
            'title' => $title,
            'summary' => $summary,
            'pic_url' => '',
            'pic_oss' => '',
            'img_list' => CommonFun::json_encode2(array()),
            'author' => '',
            'source' => '',
            'ori_url' => '',
            'content' => $content,
            'is_tmp' => 1,
            'article_type' => PublishArticleModel::CMS_TYPE_DATADAILY,
            'type' => 1,
            'coin_list' =>  CommonFun::json_encode2( $coin_id_list ),
            'is_published' => 1,
        ];

        // 判断文章是否存在
        $where = [
            'title' => $title,
            'article_type' => PublishArticleModel::CMS_TYPE_DATADAILY,
            'coin_list' =>  CommonFun::json_encode2( $coin_id_list ),
            'is_tmp' => 1,
        ];

        $find = $PublishArticleModel->field('id,is_tmp')->where($where)->find();

        if ( $find ) {
            $insert['publish_time'] = $insert['create_time'] = date("Y-m-d H:i:s");

            $PublishArticleModel->update_data($find['id'], $insert);
            $add_id = $find['id'];
        }else {
            // 添加数据
            $add_id = $PublishArticleModel->add_data($insert);
        }

        $articleRedis = new ArticlePublicRedis();
         // 处理相关文章
        $articleRedis->CreateArticleRelateAW( $add_id );

        return array( $add_id );
    }

    /**
     * 组合通用数据
     */
    private function market_report_global()
    {
        $time = strtotime( date( "Y-m-d H:00:00") );

        if ( time() - strtotime( date( 'Y-m-d H:00:00') ) > 1800 ){
            $time = strtotime( date( "Y-m-d H:30:00") );
        }

        $ApiNonceRedis = new ApiNonceRedis();

        $data = $ApiNonceRedis->Get( $ApiNonceRedis->article_market_report_global_key.$time );

        // 若有缓存数据直接返回
        if ( $data ){
            ElkLog::write( array( 'message'=> 'userPairMarketReportCache', 'is_cache' => 1 ) );
            return $data;
        }

        $CoinReportModel = CoinReportModel::getInstance();
        $market_list = $CoinReportModel->get_current_list( $CoinReportModel::TYPE_MARKET );
        $market_list_format = array();

        $this_year = date( 'Y');

        // 总市值
        $i = 0;
        $market_data = array();
        $market_data_yesterday = array();

        foreach ( $market_list as $key => $value ){
            if ( $i == 0 )
                $market_data = $value;

            if ( $i == 1)
                $market_data_yesterday = $value;
            $market_list_format[] = array(
                "number" => bcdiv( $value['total_market_usd'], 100000000 ),
                "date" => $this_year == date('Y', $value['time_stamp'] ) ?  date( 'n月j日', $value['time_stamp'] ) : date( 'Y年n月j日', $value['time_stamp'] ),
                "time" => $value['time_stamp']
            );
            $i ++;
        }

        CommonFun::array_sort( $market_list_format, "time", "ASC");

        $market_list_format = array(
            "title" => "加密货币总市值（亿USD）",
            "data"  => $market_list_format,
            "text"  => "总市值"
        );

        $market_data_format = array(
            "number" => bcdiv( $market_data['total_market_usd'], 100000000 ),
            "ups_and_downs" => bcmul( bcdiv( bcsub( $market_data['total_market_usd'], $market_data_yesterday['total_market_usd'], 2 ), $market_data_yesterday['total_market_usd'], 4 ), 100, 2)."%",
        );

        if ( floatval( $market_data_format['ups_and_downs'] ) > 0 ){
            $market_data_format['ups_and_downs'] = "+".$market_data_format['ups_and_downs'];
        }


        // 24小时成交额
        $volume_list = $CoinReportModel->get_current_list( $CoinReportModel::TYPE_VOLUME );
        $volume_list_format = array();

        $i = 0;
        $volume_data = array();
        $volume_data_yesterday = array();
        foreach ( $volume_list as $key => $value ){
            if ( $i == 0 )
                $volume_data = $value;

            if ( $i == 1)
                $volume_data_yesterday = $value;
            $volume_list_format[] = array(
                "number" => bcdiv( $value['total_volume_usd'], 100000000 ),
                "date" => $this_year == date('Y', $value['time_stamp'] ) ?  date( 'm月d日', $value['time_stamp'] ) : date( 'Y年m月d日', $value['time_stamp'] ),
                "time" => $value['time_stamp'],
            );
            $i ++;
        }

        CommonFun::array_sort( $volume_list_format, "time", "ASC");

        $volume_list_format = array(
            "title" => "24h成交额（亿USD）",
            "data"  => $volume_list_format,
            "text"  => "24h成交额"
        );

        $volume_data_format = array(
            "number" => bcdiv( $volume_data['total_volume_usd'], 100000000 ),
            "ups_and_downs" => bcmul( bcdiv( bcsub( $volume_data['total_volume_usd'], $volume_data_yesterday['total_volume_usd'], 2 ), $volume_data_yesterday['total_volume_usd'], 4 ), 100, 2)."%",
        );

        if ( floatval( $volume_data_format['ups_and_downs']) > 0 ){
            $volume_data_format['ups_and_downs'] = "+".$volume_data_format['ups_and_downs'];
        }

        // 24h排名变动
        $rank_top_list = $CoinReportModel->get_rank_24h_change();

        $CoinRuntimeModel = CoinRuntimeModel::getInstance();

        $token_list = $CoinRuntimeModel->get_key_value( 'id', 'symbol' );

        // 24h 成交额
        $PythonPushRedis = PythonPushRedis::getInstance();

        $rank_24h_volume_list = $PythonPushRedis->HashMGet( array( 1, 2, 3 ), PythonPushRedis::$rank_24h_volume_key );

        $rank_24h_volume_list = $rank_24h_volume_list ?: array();

        $rank_24h_volume_list_format = array();

        foreach ( $rank_24h_volume_list as $value ){
            $info = json_decode( $value ,true );
            $rank_24h_volume_list_format[] = array(
                'symbol'   => $token_list[$info['token_id']],
                'volume_usd' => CommonFun::fromate_num_unit( $info['volume_usd'] ),
                'token_id'   => $info['token_id']
            );
        }

        // 获取24h涨跌幅
        $rank_24h_volume_list = $PythonPushRedis->get_global_ticker_price_raise_24h_top_200();

        CommonFun::array_sort( $rank_24h_volume_list, 'pct', 'DESC', true, SORT_NUMERIC );

        $rise_top3_list = array();

        // 获取涨幅前三的
        for ( $i = 0; $i < 3; $i++ ){
            $info = array_shift( $rank_24h_volume_list );

            // 若无涨幅或者无数据则退出
            if ( $info['pct'] < 0 || !$info ){
                break;
            }

            $rise_top3_list[] = array(
                "symbol" => $token_list[$info['token_id']],
                "token_id" => $info['token_id'],
                "pct"      => round( $info['pct'], 2 ),
            );
        }

        $fall_top3_list = array();

        // 获取跌幅前三的
        for ( $i = 0; $i < 3; $i++ ){
            $info = array_pop( $rank_24h_volume_list );

            // 若无跌幅或者无数据则退出
            if ( $info['pct'] > 0 || !$info ){
                break;
            }

            $fall_top3_list[] = array(
                "symbol" => $token_list[$info['token_id']],
                "token_id" => $info['token_id'],
                "pct"      => round( $info['pct'], 2 )
            );
        }

        // 获取CTR排行前三的文章
        $ArticleCTRRedis = ArticleCTRRedis::getInstance();
        $article_id_list = $ArticleCTRRedis->SortSetZRevRange(0, -1, false);
        $article_id_list = array_slice( $article_id_list , 0,50 );
        $PublishArticleModel = PublishArticleModel::getInstance();
        $article_list = $PublishArticleModel->muti_get_data_by_id_list( $article_id_list,true,true,false );
        $article_list_format = array();

        $three_days_ago = time() - 86400;

        foreach ( $article_list as $value ){
            // 若文章为三天前文章则退出
            if (  strtotime( $value['create_time'] ) < $three_days_ago ){
                continue;
            }

            $article_list_format[] = array(
                "title" => $value['title'],
                "id"   => $value['id'],
                "h5_url" => $value['h5_url']
            );

            if ( count( $article_list_format ) == 3 ) {
                break;
            }
        }

        $data = array(
            // 总市值
            "market_data"    => $market_data_format,
            // 市值波动列表
            "market_list"    => $market_list_format,
            // 总成交额
            "volume_data"    => $volume_data_format,
            // 总成交额波动列表
            "volume_list"   => $volume_list_format,
            // 24h 排名变动
            "rank_top_list" => $rank_top_list,
            // 24h成交额排行
            "rank_24h_volume_list" => $rank_24h_volume_list_format,
            // 涨幅前三的
            "rise_top3_list" => $rise_top3_list,
            // 跌幅前三
            "fall_top3_list"  => $fall_top3_list,
            // 获取CTR排行前三的文章
            "article_list"    => $article_list_format
        );

        // 若不存在缓存直接设置
         $ApiNonceRedis->Set( CommonFun::json_encode2( $data ), $ApiNonceRedis->article_market_report_global_key.$time, 1800  );

        return $data;
    }


}